﻿using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Networking;

public class Life : CharacterBehaviour
{
    [CompilerGenerated]
    private static Action<float> <>f__am$cache13;
    [CompilerGenerated]
    private static Action<Combat> <>f__am$cache14;
    [CompilerGenerated]
    private static Action <>f__am$cache15;
    [CompilerGenerated]
    private static Action <>f__am$cache16;
    [CompilerGenerated]
    private static Action<Life> <>f__am$cache17;
    [CompilerGenerated]
    private static Action<Life> <>f__am$cache18;
    [CompilerGenerated]
    private static Action<Life> <>f__am$cache19;
    public static HashSet<Life> all = new HashSet<Life>();
    [Tooltip("isDied")]
    public Animator anim;
    public static float defaultInitialHp = 100f;
    private Coroutine dye;
    private float hpbarOffset = 1.2f;
    private static int kCmdCmdDie;
    [SyncVar(hook="OnHpChanged"), SerializeField]
    private short m_hp = ((short) defaultInitialHp);
    [SyncVar]
    private bool m_isDied;
    [SerializeField, SyncVar]
    private ushort m_maxHp = ((ushort) defaultInitialHp);
    private Action resurrectRestorer;
    public bool showHpBar = true;
    public bool showHpChangingEffect = true;

    public static  event Action<Life> onAnyDestroy;

    public static  event Action<Life> onAnyDie;

    public static  event Action<Life> onAnyResurrect;

    public event Action onDie;

    public event Action<float> onHpChanged;

    public event Action onResurrect;

    public event Action<Combat> onTakeCombat;

    static Life()
    {
        if (<>f__am$cache17 == null)
        {
            <>f__am$cache17 = new Action<Life>(Life.<onAnyDie>m__60);
        }
        onAnyDie = <>f__am$cache17;
        if (<>f__am$cache18 == null)
        {
            <>f__am$cache18 = new Action<Life>(Life.<onAnyResurrect>m__61);
        }
        onAnyResurrect = <>f__am$cache18;
        if (<>f__am$cache19 == null)
        {
            <>f__am$cache19 = new Action<Life>(Life.<onAnyDestroy>m__62);
        }
        onAnyDestroy = <>f__am$cache19;
        kCmdCmdDie = 0x37349a84;
        NetworkBehaviour.RegisterCommandDelegate(typeof(Life), kCmdCmdDie, new NetworkBehaviour.CmdDelegate(Life.InvokeCmdCmdDie));
        NetworkCRC.RegisterBehaviour("Life", 0);
    }

    public Life()
    {
        if (<>f__am$cache13 == null)
        {
            <>f__am$cache13 = new Action<float>(Life.<onHpChanged>m__5C);
        }
        this.onHpChanged = <>f__am$cache13;
        if (<>f__am$cache14 == null)
        {
            <>f__am$cache14 = new Action<Combat>(Life.<onTakeCombat>m__5D);
        }
        this.onTakeCombat = <>f__am$cache14;
        if (<>f__am$cache15 == null)
        {
            <>f__am$cache15 = new Action(Life.<onDie>m__5E);
        }
        this.onDie = <>f__am$cache15;
        if (<>f__am$cache16 == null)
        {
            <>f__am$cache16 = new Action(Life.<onResurrect>m__5F);
        }
        this.onResurrect = <>f__am$cache16;
    }

    [CompilerGenerated]
    private static void <onAnyDestroy>m__62(Life x)
    {
    }

    [CompilerGenerated]
    private static void <onAnyDie>m__60(Life x)
    {
    }

    [CompilerGenerated]
    private static void <onAnyResurrect>m__61(Life x)
    {
    }

    [CompilerGenerated]
    private static void <onDie>m__5E()
    {
    }

    [CompilerGenerated]
    private static void <onHpChanged>m__5C(float value)
    {
    }

    [CompilerGenerated]
    private static void <onResurrect>m__5F()
    {
    }

    [CompilerGenerated]
    private static void <onTakeCombat>m__5D(Combat c)
    {
    }

    protected override void Awake()
    {
        base.Awake();
        all.Add(this);
    }

    public void CallCmdDie()
    {
        if (!NetworkClient.active)
        {
            Debug.LogError("Command function CmdDie called on server.");
        }
        else if (base.isServer)
        {
            this.CmdDie();
        }
        else
        {
            NetworkWriter writer = new NetworkWriter();
            writer.Write((short) 0);
            writer.Write((short) ((ushort) 5));
            writer.WritePackedUInt32((uint) kCmdCmdDie);
            writer.Write(base.GetComponent<NetworkIdentity>().netId);
            base.SendCommandInternal(writer, 0, "CmdDie");
        }
    }

    [Command]
    private void CmdDie()
    {
        this.DieInternal();
    }

    public void Die()
    {
        this.CallCmdDie();
    }

    private void DieInternal()
    {
        <DieInternal>c__AnonStorey4D storeyd = new <DieInternal>c__AnonStorey4D {
            <>f__this = this
        };
        if (!this.isDied)
        {
            this.resurrectRestorer = null;
            this.isDied = true;
            this.hp = 0f;
            if (this.anim != null)
            {
                this.anim.SetBool("isDied", true);
                this.resurrectRestorer = (Action) Delegate.Combine(this.resurrectRestorer, new Action(storeyd.<>m__64));
            }
            if (!base.isPlayer)
            {
                <DieInternal>c__AnonStorey49 storey = new <DieInternal>c__AnonStorey49();
                MonoBehaviour[] behaviourArray = base.self.GetComponents<MonoBehaviour>();
                for (int j = 0; j < behaviourArray.Length; j++)
                {
                    storey.comp = behaviourArray[j];
                    <DieInternal>c__AnonStorey48 storey2 = new <DieInternal>c__AnonStorey48 {
                        <>f__ref$73 = storey
                    };
                    if (((storey.comp != this) && !(storey.comp is FrameAnimator)) && !(storey.comp is NetworkProximityChecker))
                    {
                        storey2.enabled = storey.comp.enabled;
                        storey.comp.enabled = false;
                        this.resurrectRestorer = (Action) Delegate.Combine(this.resurrectRestorer, new Action(storey2.<>m__65));
                    }
                }
            }
            <DieInternal>c__AnonStorey4B storeyb = new <DieInternal>c__AnonStorey4B();
            Collider[] components = base.self.GetComponents<Collider>();
            for (int i = 0; i < components.Length; i++)
            {
                storeyb.co = components[i];
                <DieInternal>c__AnonStorey4A storeya = new <DieInternal>c__AnonStorey4A {
                    <>f__ref$75 = storeyb,
                    layer = storeyb.co.gameObject.layer
                };
                storeyb.co.gameObject.layer = GameLayers.Effect.index;
                this.resurrectRestorer = (Action) Delegate.Combine(this.resurrectRestorer, new Action(storeya.<>m__66));
            }
            storeyd.rb = base.GetComponent<Rigidbody>();
            if (storeyd.rb != null)
            {
                <DieInternal>c__AnonStorey4C storeyc = new <DieInternal>c__AnonStorey4C {
                    <>f__ref$77 = storeyd,
                    drag = storeyd.rb.drag
                };
                storeyd.rb.drag = 1f;
                this.resurrectRestorer = (Action) Delegate.Combine(this.resurrectRestorer, new Action(storeyc.<>m__67));
            }
            this.onDie();
            onAnyDie(this);
        }
    }

    private void Dye()
    {
        <Dye>c__AnonStorey46 storey = new <Dye>c__AnonStorey46();
        if (this.dye != null)
        {
            base.StopCoroutine(this.dye);
        }
        storey.mrs = base.self.GetComponentsInChildren<Renderer>(true);
        this.dye = this.StartAnimateColor(Color.red, Color.white, 0.2f, new Action<Color>(storey.<>m__63), null);
    }

    protected static void InvokeCmdCmdDie(NetworkBehaviour obj, NetworkReader reader)
    {
        if (!NetworkServer.active)
        {
            Debug.LogError("Command CmdDie called on client.");
        }
        else
        {
            ((Life) obj).CmdDie();
        }
    }

    public override void OnDeserialize(NetworkReader reader, bool initialState)
    {
        base.OnDeserialize(reader, initialState);
        if (initialState)
        {
            this.m_hp = (short) reader.ReadPackedUInt32();
            this.m_maxHp = (ushort) reader.ReadPackedUInt32();
            this.m_isDied = reader.ReadBoolean();
        }
        else
        {
            int num = (int) reader.ReadPackedUInt32();
            if ((num & 1) != 0)
            {
                this.OnHpChanged((short) reader.ReadPackedUInt32());
            }
            if ((num & 2) != 0)
            {
                this.m_maxHp = (ushort) reader.ReadPackedUInt32();
            }
            if ((num & 4) != 0)
            {
                this.m_isDied = reader.ReadBoolean();
            }
        }
    }

    private void OnDestroy()
    {
        this.isDestroyed = true;
        onAnyDestroy(this);
        all.Remove(this);
    }

    private void OnHpChanged(short hp)
    {
        short num = this.m_hp;
        if (this.showHpChangingEffect)
        {
            HpChangingText.Spwan(base.transform.position, (float) (hp - num), base.self.gameObject.tag == GameTags.Player);
        }
        if (hp <= 0)
        {
            this.DieInternal();
        }
        else
        {
            this.ResurrectInternal();
        }
        this.Networkm_hp = hp;
        this.onHpChanged((float) hp);
    }

    public override bool OnSerialize(NetworkWriter writer, bool forceAll)
    {
        bool flag2 = base.OnSerialize(writer, forceAll);
        if (forceAll)
        {
            writer.WritePackedUInt32((uint) this.m_hp);
            writer.WritePackedUInt32(this.m_maxHp);
            writer.Write(this.m_isDied);
            return true;
        }
        bool flag = false;
        if ((base.syncVarDirtyBits & 1) != 0)
        {
            if (!flag)
            {
                writer.WritePackedUInt32(base.syncVarDirtyBits);
                flag = true;
            }
            writer.WritePackedUInt32((uint) this.m_hp);
        }
        if ((base.syncVarDirtyBits & 2) != 0)
        {
            if (!flag)
            {
                writer.WritePackedUInt32(base.syncVarDirtyBits);
                flag = true;
            }
            writer.WritePackedUInt32(this.m_maxHp);
        }
        if ((base.syncVarDirtyBits & 4) != 0)
        {
            if (!flag)
            {
                writer.WritePackedUInt32(base.syncVarDirtyBits);
                flag = true;
            }
            writer.Write(this.m_isDied);
        }
        if (!flag)
        {
            writer.WritePackedUInt32(base.syncVarDirtyBits);
        }
        return (flag | flag2);
    }

    public override void OnStartClient()
    {
        base.OnStartClient();
        if (this.isDied)
        {
            this.DieInternal();
        }
    }

    [Server]
    public void Resurrect()
    {
        if (!NetworkServer.active)
        {
            Debug.LogWarning("[Server] function 'System.Void Life::Resurrect()' called on client");
        }
        else
        {
            this.ResurrectInternal();
        }
    }

    private void ResurrectInternal()
    {
        if (this.isDied)
        {
            if (this.resurrectRestorer != null)
            {
                this.resurrectRestorer();
            }
            this.isDied = false;
            this.hp = this.maxHp;
            this.onResurrect();
            onAnyResurrect(this);
        }
    }

    protected virtual void Start()
    {
        if (this.anim == null)
        {
            this.anim = base.self.GetComponentInChildren<Animator>();
        }
        if (this.showHpBar)
        {
            Hpbar.Create(this, this.hpbarOffset);
        }
    }

    public void TakeCombat(Combat combat)
    {
        if (NetworkUtility.isServer)
        {
            this.hp -= combat.damage;
            if (combat.damage > 0f)
            {
                this.Dye();
            }
            this.onTakeCombat(combat);
        }
    }

    private void UNetVersion()
    {
    }

    private void Update()
    {
        if (base.hasAuthority && (base.self.transform.position.y < -5f))
        {
            Respawn closest = Respawn.GetClosest(base.transform.position);
            if (closest != null)
            {
                base.self.transform.position = closest.transform.position;
            }
            this.Die();
        }
    }

    public float hp
    {
        get
        {
            return (float) this.m_hp;
        }
        set
        {
            value = Mathf.Min(value, this.maxHp);
            this.Networkm_hp = (short) value;
        }
    }

    public bool isDestroyed { get; private set; }

    public bool isDied
    {
        get
        {
            return this.m_isDied;
        }
        set
        {
            this.Networkm_isDied = value;
        }
    }

    public float maxHp
    {
        get
        {
            return (float) this.m_maxHp;
        }
        set
        {
            this.Networkm_maxHp = (ushort) value;
        }
    }

    public short Networkm_hp
    {
        get
        {
            return this.m_hp;
        }
        [param: In]
        set
        {
            if (NetworkServer.localClientActive && !base.syncVarHookGuard)
            {
                base.syncVarHookGuard = true;
                this.OnHpChanged(value);
                base.syncVarHookGuard = false;
            }
            base.SetSyncVar<short>(value, ref this.m_hp, 1);
        }
    }

    public bool Networkm_isDied
    {
        get
        {
            return this.m_isDied;
        }
        [param: In]
        set
        {
            base.SetSyncVar<bool>(value, ref this.m_isDied, 4);
        }
    }

    public ushort Networkm_maxHp
    {
        get
        {
            return this.m_maxHp;
        }
        [param: In]
        set
        {
            base.SetSyncVar<ushort>(value, ref this.m_maxHp, 2);
        }
    }

    [CompilerGenerated]
    private sealed class <DieInternal>c__AnonStorey48
    {
        internal Life.<DieInternal>c__AnonStorey49 <>f__ref$73;
        internal bool enabled;

        internal void <>m__65()
        {
            this.<>f__ref$73.comp.enabled = this.enabled;
        }
    }

    [CompilerGenerated]
    private sealed class <DieInternal>c__AnonStorey49
    {
        internal MonoBehaviour comp;
    }

    [CompilerGenerated]
    private sealed class <DieInternal>c__AnonStorey4A
    {
        internal Life.<DieInternal>c__AnonStorey4B <>f__ref$75;
        internal int layer;

        internal void <>m__66()
        {
            this.<>f__ref$75.co.gameObject.layer = this.layer;
        }
    }

    [CompilerGenerated]
    private sealed class <DieInternal>c__AnonStorey4B
    {
        internal Collider co;
    }

    [CompilerGenerated]
    private sealed class <DieInternal>c__AnonStorey4C
    {
        internal Life.<DieInternal>c__AnonStorey4D <>f__ref$77;
        internal float drag;

        internal void <>m__67()
        {
            this.<>f__ref$77.rb.drag = this.drag;
        }
    }

    [CompilerGenerated]
    private sealed class <DieInternal>c__AnonStorey4D
    {
        internal Life <>f__this;
        internal Rigidbody rb;

        internal void <>m__64()
        {
            this.<>f__this.anim.SetBool("isDied", false);
        }
    }

    [CompilerGenerated]
    private sealed class <Dye>c__AnonStorey46
    {
        internal Renderer[] mrs;

        internal void <>m__63(Color x)
        {
            <Dye>c__AnonStorey47 storey = new <Dye>c__AnonStorey47 {
                <>f__ref$70 = this,
                x = x
            };
            this.mrs.Foreach<Renderer>(new Action<Renderer>(storey.<>m__68));
        }

        private sealed class <Dye>c__AnonStorey47
        {
            internal Life.<Dye>c__AnonStorey46 <>f__ref$70;
            internal Color x;

            internal void <>m__68(Renderer m)
            {
                if (m != null)
                {
                    m.material.color = this.x;
                }
            }
        }
    }
}

